#ifndef __NET__MODULE__H__
#define __NET__MODULE__H__
#include "PluginModule/INet.h"
#include "PluginModule/INetModule.h"
#include "PluginModule/ILogModule.h"

namespace FragrantGrass
{
	class NetModule : public INetModule
	{
	public:
		NetModule(IPluginManager* p);
		virtual ~NetModule();

		virtual bool Init() override;
		virtual bool AfterInit() override;

	private:
		typedef std::map<int, std::list<NET_MESSAGE_HANDLER_FUNCTOR_PTR>> NetMessageHandleMap;
		typedef std::list<NET_EVENT_HANDLER_FUNCTOR_PTR> NetEventHandleMap;
		typedef std::list<NET_MESSAGE_HANDLER_FUNCTOR_PTR> NetMessageHandleList;

	public:
		virtual int init_as_client(const char* ip, unsigned short port);
		virtual int init_as_server(unsigned int max_client_cnt, unsigned short port, int cpu_count = 4);
		virtual int expand_buffer_size(unsigned int size = 1024 * 1024 * 20);
		virtual bool register_net_message_handler(int id, const NET_MESSAGE_HANDLER_FUNCTOR_PTR& cb);
		virtual bool register_net_message_handler(const NET_MESSAGE_HANDLER_FUNCTOR_PTR& cb);
		virtual bool register_net_event_handler(const NET_EVENT_HANDLER_FUNCTOR_PTR& cb);

		virtual bool send_msg_with_out_head(int16_t id, const std::string& msg, SOCK fd);
		virtual bool send_msg_with_out_head(const uint16_t nMsgID, const std::string& xData, const SOCK nSockIndex, const GUID id);
		virtual bool send_msg_to_all_client_with_out_head(int16_t id, const std::string& msg);

		virtual bool send_protobuf_message(const uint16_t nMsgID, const google::protobuf::Message& xData, const SOCK nSockIndex);
		virtual bool send_protobuf_message(const uint16_t nMsgID, const google::protobuf::Message& xData, const SOCK nSockIndex, const GUID nPlayer);
		virtual bool send_protobuf_message(const uint16_t nMsgID, const google::protobuf::Message& xData, const SOCK nSockIndex, const std::vector<GUID>* pClientIDList);
		virtual bool send_protobuf_message(const uint16_t nMsgID, const std::string& strData, const SOCK nSockIndex, const std::vector<GUID>* pClientIDList);
		virtual bool send_protobuf_message_to_all_clients(const uint16_t nMsgID, const google::protobuf::Message& xData);

		virtual bool Execute() override;
		void heart_beat();

		virtual INet* getNet();

	protected:
		void handle_net_msg(SOCK fd,int id, const char* msg,uint32_t len);
		void handle_net_event(SOCK fd, FG_NET_EVENT events, INet* net);

	private:
		INT64 m_LastTime;
		INet* m_pkNet;
		ILogModule* m_pkLogModule;
		NetMessageHandleMap m_kNetMessageHandles;
		NetEventHandleMap m_kNetEventCallbackHandles;
		NetMessageHandleList m_kNetMessageCallbackHandles;

	};
}
#endif//__NET__MODULE__H__